use crate::src::struct_and_type::{
    BinaryHeap, BinaryHeapCompareFunc, BinaryHeapType, BinaryHeapValue,
};
use :: libc;
extern "C" {
    fn malloc(_: u64) -> *mut libc::c_void;
    fn realloc(_: *mut libc::c_void, _: u64) -> *mut libc::c_void;
    fn free(_: *mut libc::c_void);
}
pub const BINARY_HEAP_TYPE_MAX: BinaryHeapType = 1;
pub const BINARY_HEAP_TYPE_MIN: BinaryHeapType = 0;
extern "C" fn binary_heap_cmp(
    mut heap: *mut BinaryHeap,
    mut data1: BinaryHeapValue,
    mut data2: BinaryHeapValue,
) -> i32 {
    if (unsafe { (*heap).heap_type }) as u32 == BINARY_HEAP_TYPE_MIN as i32 as u32 {
        return unsafe { ((*heap).compare_func).expect("non-null function pointer")(data1, data2) };
    } else {
        return -(unsafe {
            ((*heap).compare_func).expect("non-null function pointer")(data1, data2)
        });
    };
}
#[no_mangle]
pub extern "C" fn binary_heap_new(
    mut heap_type: BinaryHeapType,
    mut compare_func: BinaryHeapCompareFunc,
) -> *mut BinaryHeap {
    let mut heap: *mut BinaryHeap = 0 as *mut BinaryHeap;
    heap = (unsafe { malloc(::core::mem::size_of::<BinaryHeap>() as u64) }) as *mut BinaryHeap;
    if heap.is_null() {
        return 0 as *mut BinaryHeap;
    }
    (unsafe { (*heap).heap_type = heap_type });
    (unsafe { (*heap).num_values = 0 as i32 as u32 });
    (unsafe { (*heap).compare_func = compare_func });
    (unsafe { (*heap).alloced_size = 16 as i32 as u32 });
    (unsafe {
        (*heap).values = malloc(
            (::core::mem::size_of::<BinaryHeapValue>() as u64)
                .wrapping_mul((*heap).alloced_size as u64),
        ) as *mut BinaryHeapValue
    });
    if (unsafe { (*heap).values }).is_null() {
        (unsafe { free(heap as *mut libc::c_void) });
        return 0 as *mut BinaryHeap;
    }
    return heap;
}
#[no_mangle]
pub extern "C" fn binary_heap_free(mut heap: *mut BinaryHeap) {
    (unsafe { free((*heap).values as *mut libc::c_void) });
    (unsafe { free(heap as *mut libc::c_void) });
}
#[no_mangle]
pub extern "C" fn binary_heap_insert(mut heap: *mut BinaryHeap, mut value: BinaryHeapValue) -> i32 {
    let mut new_values: *mut BinaryHeapValue = 0 as *mut BinaryHeapValue;
    let mut index: u32 = 0;
    let mut new_size: u32 = 0;
    let mut parent: u32 = 0;
    if (unsafe { (*heap).num_values }) >= (unsafe { (*heap).alloced_size }) {
        new_size = (unsafe { (*heap).alloced_size }).wrapping_mul(2 as i32 as u32);
        new_values = (unsafe {
            realloc(
                (*heap).values as *mut libc::c_void,
                (::core::mem::size_of::<BinaryHeapValue>() as u64).wrapping_mul(new_size as u64),
            )
        }) as *mut BinaryHeapValue;
        if new_values.is_null() {
            return 0 as i32;
        }
        (unsafe { (*heap).alloced_size = new_size });
        (unsafe { (*heap).values = new_values });
    }
    index = unsafe { (*heap).num_values };
    (unsafe { (*heap).num_values = ((*heap).num_values).wrapping_add(1) });
    (unsafe { (*heap).num_values });
    while index > 0 as i32 as u32 {
        parent = index
            .wrapping_sub(1 as i32 as u32)
            .wrapping_div(2 as i32 as u32);
        if binary_heap_cmp(
            heap,
            unsafe { *((*heap).values).offset(parent as isize) },
            value,
        ) < 0 as i32
        {
            break;
        }
        let fresh0 = unsafe { &mut (*((*heap).values).offset(index as isize)) };
        *fresh0 = unsafe { *((*heap).values).offset(parent as isize) };
        index = parent;
    }
    let fresh1 = unsafe { &mut (*((*heap).values).offset(index as isize)) };
    *fresh1 = value;
    return 1 as i32;
}
#[no_mangle]
pub extern "C" fn binary_heap_pop(mut heap: *mut BinaryHeap) -> BinaryHeapValue {
    let mut result: BinaryHeapValue = 0 as *mut libc::c_void;
    let mut new_value: BinaryHeapValue = 0 as *mut libc::c_void;
    let mut index: u32 = 0;
    let mut next_index: u32 = 0;
    let mut child1: u32 = 0;
    let mut child2: u32 = 0;
    if (unsafe { (*heap).num_values }) == 0 as i32 as u32 {
        return 0 as *mut libc::c_void;
    }
    result = unsafe { *((*heap).values).offset(0 as i32 as isize) };
    new_value = unsafe {
        *((*heap).values).offset(((*heap).num_values).wrapping_sub(1 as i32 as u32) as isize)
    };
    (unsafe { (*heap).num_values = ((*heap).num_values).wrapping_sub(1) });
    (unsafe { (*heap).num_values });
    index = 0 as i32 as u32;
    loop {
        child1 = index
            .wrapping_mul(2 as i32 as u32)
            .wrapping_add(1 as i32 as u32);
        child2 = index
            .wrapping_mul(2 as i32 as u32)
            .wrapping_add(2 as i32 as u32);
        if child1 < (unsafe { (*heap).num_values })
            && binary_heap_cmp(heap, new_value, unsafe {
                *((*heap).values).offset(child1 as isize)
            }) > 0 as i32
        {
            if child2 < (unsafe { (*heap).num_values })
                && binary_heap_cmp(
                    heap,
                    unsafe { *((*heap).values).offset(child1 as isize) },
                    unsafe { *((*heap).values).offset(child2 as isize) },
                ) > 0 as i32
            {
                next_index = child2;
            } else {
                next_index = child1;
            }
        } else if child2 < (unsafe { (*heap).num_values })
            && binary_heap_cmp(heap, new_value, unsafe {
                *((*heap).values).offset(child2 as isize)
            }) > 0 as i32
        {
            next_index = child2;
        } else {
            let fresh2 = unsafe { &mut (*((*heap).values).offset(index as isize)) };
            *fresh2 = new_value;
            break;
        }
        let fresh3 = unsafe { &mut (*((*heap).values).offset(index as isize)) };
        *fresh3 = unsafe { *((*heap).values).offset(next_index as isize) };
        index = next_index;
    }
    return result;
}
#[no_mangle]
pub extern "C" fn binary_heap_num_entries(mut heap: *mut BinaryHeap) -> u32 {
    return unsafe { (*heap).num_values };
}
